package unamur.iodass.accountancy;

import java.util.HashMap;

import org.apache.log4j.Logger;

import unamur.iodass.app.ProjectProperties;
import unamur.iodass.catalog.CatalogHandler;
import unamur.iodass.communication.Communication;
import unamur.iodass.communication.messages.BookDeal;
import unamur.iodass.communication.messages.BookStore;
import unamur.iodass.communication.messages.Catalog;
import unamur.iodass.communication.messages.ContratBookStore;


public class Accountancy {
	private static final Logger logger = Logger.getLogger(Accountancy.class);
	
	private static volatile Accountancy instance;
	private Communication com = Communication.getInstance();
	private float marge; // en pourcent ex 0.3
	private HashMap<Long, Integer> prixISBN;
	private BookStore bs;
	CatalogHandler catalogHandler;
	private int debitUnit;


	public static Accountancy getInstance() {
		if (instance == null) {
			synchronized (Accountancy.class) {
				if (instance == null) {
					instance = new Accountancy();
				}
			}
		}
		return instance;
	}


	private Accountancy() {
		prixISBN = new HashMap<Long, Integer>();
		catalogHandler = CatalogHandler.getInstance();
		
		debitUnit = Integer.valueOf( ProjectProperties.getProjectProperty("debitUnit"));
		marge = Float.valueOf( ProjectProperties.getProjectProperty("marge"));
	}

	public void handleBookDeal(BookDeal bookDeal) {
		logger.info("BOOKSTORE : " + this.bs.getName());
		

		if (catalogHandler.estDisponible(bookDeal.getIsbn())) {
			int prixAuMinore = getPrixMinimum(bookDeal);
			if (bookDeal.getMinimum() > prixAuMinore) {  // book store peut proposer moins
				
				if ((bookDeal.getMinimum() - debitUnit) > prixAuMinore) {
					int propositionPrix = bookDeal.getMinimum() - debitUnit;
					com.async(new BookDeal(bs, bookDeal.getIsbn(), propositionPrix, bookDeal.getRound(), bookDeal.getIpBookStoreHost(), bookDeal.getPortBookStoreHost()), 
							 bookDeal.getIpBookStoreHost(), bookDeal.getPortBookStoreHost());  // envoyer l'objet BookDeal à l'Host bookstore
				
					
				}else {
					int dernierePropositionPrix = prixAuMinore; // On propose le prix le plus bas possible
					com.async(new BookDeal(bs, bookDeal.getIsbn(), dernierePropositionPrix, bookDeal.getRound(), bookDeal.getIpBookStoreHost(), bookDeal.getPortBookStoreHost()),
							bookDeal.getIpBookStoreHost(), bookDeal.getPortBookStoreHost());
				}
			}
			
			else { // book store ne peut pas proposer moins
				com.async(new BookDeal(bs, bookDeal.getIsbn(), -1, bookDeal.getRound(), bookDeal.getIpBookStoreHost(), bookDeal.getPortBookStoreHost()),
						bookDeal.getIpBookStoreHost(), bookDeal.getPortBookStoreHost()); // -1 : On se retire du deal
			}
		}
		else { // livre non disponible
			com.async(new BookDeal(bs, bookDeal.getIsbn(), 0, bookDeal.getRound(), bookDeal.getIpBookStoreHost(), bookDeal.getPortBookStoreHost()),
					bookDeal.getIpBookStoreHost(), bookDeal.getPortBookStoreHost()); // livre non disponible
		}
	}


	public void generateBookStorePrice() {
		CatalogHandler catalogHandler = CatalogHandler.getInstance();
		Catalog catalog  = (Catalog) catalogHandler.getCatalog();
		int generatedPrice = 0;
		for (int i=0; i<catalog.getSize(); i++) {
			generatedPrice = 7 + (int)(Math.random() * ((16 - 7) + 1)); // [7..16]
			logger.debug("ISBN : " + catalog.getBooks().get(i).getIsbn() + "\t " + generatedPrice);
			prixISBN.put(catalog.getBooks().get(i).getIsbn(), generatedPrice);
		}
	}

	public int getPrixMinimum(BookDeal bookDeal) {
		return getBookStorePrice(bookDeal)- (int) (this.marge * getBookStorePrice(bookDeal));
	}

	public int getBookStorePrice(BookDeal bookDeal) {
		return prixISBN.get(bookDeal.getIsbn());
	}


	public void setMarge(float pourcentage) {
		this.marge = pourcentage;
	}

	public void setBookStore(BookStore bs) {
		this.bs = bs;
	}



}
